//------------------------------------------------------------
//  Filename: calendar.v
//   
//  Author  : wlduan@gmail.com
//  Revise  : 2016-10-11 08:21
//  Description: 
//   
//  Copyright (C) 2014, YRBD, Inc. 					      
//  All Rights Reserved.                                       
//-------------------------------------------------------------
//
`timescale 1ns/1ps
 
module CALENDAR ( 
    input  wire        clk_100mhz,  
    input  wire        resetn,  

    input  wire [31:0] rtc_ctrl,
    output wire [15:0] rtc_data_read,
    output wire        rtc_trans_over,

    output wire        rtc_scl,
    inout  wire        rtc_sda,

    input  wire        load_time,  
    output reg  [31:0] pcf8563_date,
    output reg  [31:0] pcf8563_time,

    output reg  [31:0] local_date,
    output reg  [31:0] local_time    
);  
//--------------------------------------------------------
wire clk = clk_100mhz;
wire rst = ~resetn;
//--------------------------------------------------------
IIC_INTF IIC_CONFIG_inst0( 
    .clk            ( clk_100mhz       ) ,
    .rst            ( ~resetn          ) ,

    .iic_addr_size  ( 1'b0             ) ,
    .iic_devid      ( 8'ha2            ) ,
    .iic_ctrl       ( rtc_ctrl         ) ,
    .iic_data_read  ( rtc_data_read    ) ,
    .iic_trans_over ( rtc_trans_over   ) ,

    .iic_sclk       ( rtc_scl          ) ,
    .iic_sda        ( rtc_sda          ) 
);  
//--------------------------------------------------------
reg[31:0] second_pulse;
//--------------------------------------------------------
always @(posedge clk,posedge rst) begin
    if(rst)begin 
        second_pulse <= 0;    
    end 
    else begin 
        second_pulse <= (second_pulse < 100000000)?(second_pulse + 1):0;    
    end 
end 
//--------------------------------------------------------
wire pluse_1hz = (second_pulse == 1060000000);
//--------------------------------------------------------
reg[7:0] second_counter;
//--------------------------------------------------------
always @(posedge clk,posedge rst) begin
    if(rst)begin 
       second_counter <= 8'h0;
    end 
    else if(load_time) begin 
        second_counter <= pcf8563_time[7:0]; 
    end
    else if(pluse_1hz)begin 
        if(second_counter == 8'h59) second_counter <= 0;
          else if(second_counter[3:0] == 4'h9) begin
                second_counter[7:4] <= (second_counter[7:4] + 4'h1); 
                second_counter[3:0] <= 4'h0;
          end
          else begin
              second_counter[3:0] <= second_counter[3:0] + 4'h1;
          end    
    end 
end 
reg[7:0] minutes_counter;
//--------------------------------------------------------
always @(posedge clk,posedge rst) begin
    if(rst)begin 
        minutes_counter <= 8'h0;    
    end 
    else if(load_time) begin 
        minutes_counter <= pcf8563_time[15:8]; 
    end     
    else if(pluse_1hz&&(second_counter == 8'h59))begin 
        if(minutes_counter > 8'h59) minutes_counter <= 0;
          else if(minutes_counter[3:0] == 4'h9) begin
                minutes_counter[7:4] <= (minutes_counter[7:4] + 4'h1); 
                minutes_counter[3:0] <= 4'h0;
          end
          else begin
              minutes_counter[3:0] <= minutes_counter[3:0] + 4'h1;
          end  
    end 
    else if((minutes_counter > 8'h59)||(minutes_counter[3:0] > 4'h9) )begin 
        minutes_counter <= 0;    
    end
end 
reg[7:0] hours_counter;
//--------------------------------------------------------
always @(posedge clk,posedge rst) begin
    if(rst)begin 
        hours_counter <= 0;    
    end 
    else if(load_time) begin 
        hours_counter <= pcf8563_time[24:16]; 
    end     
    else if(pluse_1hz&&(minutes_counter == 8'h59)&&(second_counter == 8'h59))begin 
        if(hours_counter > 8'h23) hours_counter <= 0;
          else if(hours_counter[3:0] == 4'h9) begin
                hours_counter[7:4] <= (hours_counter[7:4] + 4'h1); 
                hours_counter[3:0] <= 4'h0;
          end
          else begin
              hours_counter[3:0] <= hours_counter[3:0] + 4'h1;
          end
    end
    else if((hours_counter > 8'h23)||(hours_counter[3:0] > 4'h9) )begin 
        hours_counter <= 0;    
    end
end 
reg[7:0] years;
//--------------------------------------------------------
always @(posedge clk,posedge rst) begin
    if(rst)begin 
        years <= 0;    
    end 
    else if(load_time) begin 
        years <= pcf8563_date[31:16]; 
    end
    else if((years[7:4] > 4'h9)||(years[3:0] > 4'h9)) begin
        years <= 0;    
    end
end 
reg[7:0] months;
//--------------------------------------------------------
always @(posedge clk,posedge rst) begin
    if(rst)begin 
        months <= 0;    
    end 
    else if(load_time) begin 
        months <= pcf8563_date[15:8]; 
    end
    else if((months > 8'h12)||(months[3:0] > 9)) begin
        months <= 1;    
    end    
end 
reg[7:0] days;
//--------------------------------------------------------
always @(posedge clk,posedge rst) begin
    if(rst)begin 
        days <= 0;    
    end 
    else if(load_time) begin 
        days <= pcf8563_date[7:0]; 
    end
    else if((days > 8'h31)||(days[3:0] > 9)) begin
        days <= 1;    
    end     
end 
//--------------------------------------------------------
always @(posedge clk,posedge rst) begin
    if(rst)begin 
        local_date <= 0;        
        local_time <= 0;        
    end 
    else begin 
        local_date <= {8'h0,years,months,days};    
        local_time <= {8'h0,hours_counter,minutes_counter,second_counter};    
    end 
end 

endmodule
